home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 24 / Amiga Format AFCD24 (Feb 1998, Issue 108).iso / -in_the_mag- / emulation / amiga / uae-0.7.0b2 / src / svga.c < prev    next >
C/C++ Source or Header  |  1998-01-20  |  23KB  |  925 lines

  1.  /*
  2.   * UAE - The Un*x Amiga Emulator
  3.   *
  4.   * SVGAlib interface.
  5.   *
  6.   * (c) 1995 Bernd Schmidt
  7.   */
  8.  
  9. #include "sysconfig.h"
  10. #include "sysdeps.h"
  11.  
  12. #include <assert.h>
  13. #include <ctype.h>
  14. #include <signal.h>
  15. #include <vga.h>
  16. #include <vgamouse.h>
  17. #include <vgakeyboard.h>
  18.  
  19. #include "config.h"
  20. #include "options.h"
  21. #include "threaddep/penguin.h"
  22. #include "uae.h"
  23. #include "memory.h"
  24. #include "custom.h"
  25. #include "readcpu.h"
  26. #include "newcpu.h"
  27. #include "keyboard.h"
  28. #include "xwin.h"
  29. #include "keybuf.h"
  30. #include "tui.h"
  31. #include "gui.h"
  32. #include "picasso96.h"
  33.  
  34. #define SCODE_CB_UP    103    /* Cursor key block. */
  35. #define SCODE_CB_LEFT    105
  36. #define SCODE_CB_RIGHT    106
  37. #define SCODE_CB_DOWN    108
  38.  
  39. #define SCODE_INSERT    110
  40. #define SCODE_HOME    102
  41. #define SCODE_PGUP    104
  42. #define SCODE_DELETE    111
  43. #define SCODE_END    107
  44. #define SCODE_PGDN    109
  45.  
  46. #define SCODE_PRTSCR    99
  47. #define SCODE_SLOCK    70
  48. #define SCODE_BREAK    119
  49.  
  50. #define SCODE_NUMLOCK    69
  51.  
  52. #define SCODE_KEYPAD0    82
  53. #define SCODE_KEYPAD1    79
  54. #define SCODE_KEYPAD2    80
  55. #define SCODE_KEYPAD3    81
  56. #define SCODE_KEYPAD4    75
  57. #define SCODE_KEYPAD5    76
  58. #define SCODE_KEYPAD6    77
  59. #define SCODE_KEYPAD7    71
  60. #define SCODE_KEYPAD8    72
  61. #define SCODE_KEYPAD9    73
  62. #define SCODE_KEYPADRET    96
  63. #define SCODE_KEYPADADD    78
  64. #define SCODE_KEYPADSUB    74
  65. #define SCODE_KEYPADMUL    55
  66. #define SCODE_KEYPADDIV    98
  67. #define SCODE_KEYPADDOT 83
  68.  
  69. #define SCODE_Q        16
  70. #define SCODE_W        17
  71. #define SCODE_E        18
  72. #define SCODE_R        19
  73. #define SCODE_T        20
  74. #define SCODE_Y        21
  75. #define SCODE_U        22
  76. #define SCODE_I        23
  77. #define SCODE_O        24
  78. #define SCODE_P        25
  79.  
  80. #define SCODE_A        30
  81. #define SCODE_S        31
  82. #define SCODE_D        32
  83. #define SCODE_F        33
  84. #define SCODE_G        34
  85. #define SCODE_H        35
  86. #define SCODE_J        36
  87. #define SCODE_K        37
  88. #define SCODE_L        38
  89.  
  90. #define SCODE_Z        44
  91. #define SCODE_X        45
  92. #define SCODE_C        46
  93. #define SCODE_V        47
  94. #define SCODE_B        48
  95. #define SCODE_N        49
  96. #define SCODE_M        50
  97.  
  98. #define SCODE_ESCAPE    1
  99. #define SCODE_ENTER    28
  100. #define SCODE_RCONTROL    97
  101. #define SCODE_CONTROL    97
  102. #define SCODE_RALT    100
  103. #define SCODE_LCONTROL    29
  104. #define SCODE_LALT    56
  105. #define SCODE_SPACE    57
  106.  
  107. #define SCODE_F1    59
  108. #define SCODE_F2    60
  109. #define SCODE_F3    61
  110. #define SCODE_F4    62
  111. #define SCODE_F5    63
  112. #define SCODE_F6    64
  113. #define SCODE_F7    65
  114. #define SCODE_F8    66
  115. #define SCODE_F9    67
  116. #define SCODE_F10    68
  117. #define SCODE_F11    87
  118. #define SCODE_F12    88
  119.  
  120. #define SCODE_0        11
  121. #define SCODE_1        2
  122. #define SCODE_2        3
  123. #define SCODE_3        4
  124. #define SCODE_4        5
  125. #define SCODE_5        6
  126. #define SCODE_6         7
  127. #define SCODE_7        8
  128. #define SCODE_8        9
  129. #define SCODE_9     10
  130.  
  131. #define SCODE_LSHIFT    42
  132. #define SCODE_RSHIFT    54
  133. #define SCODE_TAB    15
  134.  
  135. #define SCODE_BS    14
  136.  
  137. #define SCODE_asciicircum    41
  138.  
  139. #define SCODE_bracketleft    26
  140. #define SCODE_bracketright    27
  141. #define SCODE_comma    51
  142. #define SCODE_period    52
  143. #define SCODE_slash    53
  144. #define SCODE_semicolon    39
  145. #define SCODE_grave    40
  146. #define SCODE_minus    12
  147. #define SCODE_equal    13
  148. #define SCODE_numbersign    43
  149. #define SCODE_ltgt    86
  150.  
  151. #define SCODE_LWIN95 125
  152. #define SCODE_RWIN95 126
  153. #define SCODE_MWIN95 127
  154.  
  155. void setup_brkhandler(void)
  156. {
  157. }
  158.  
  159. static int bitdepth, bit_unit, using_linear, vgamode, current_vgamode, gui_requested;
  160. static vga_modeinfo modeinfo;
  161. static char *linear_mem = NULL;
  162. static int need_dither;
  163. static int screen_is_picasso;
  164. static int picasso_vgamode = -1;
  165. static char picasso_invalid_lines[1200];
  166.  
  167. static uae_u8 dither_buf[1000]; /* I hate having to think about array bounds */
  168.  
  169. #define MAX_SCREEN_MODES 9
  170.  
  171. static int x_size_table[MAX_SCREEN_MODES] = { 320, 320, 320, 640, 640, 800, 1024, 1152, 1280 };
  172. static int y_size_table[MAX_SCREEN_MODES] = { 200, 240, 400, 350, 480, 600, 768, 864, 1024 };
  173.  
  174. static int vga_mode_table[MAX_SCREEN_MODES][MAX_COLOR_MODES+1] =
  175.  { { G320x200x256, G320x200x32K, G320x200x64K, G320x200x256, G320x200x16, G320x200x16M32 },
  176.    { G320x240x256, -1, -1, G320x240x256, -1, -1 },
  177.    { G320x400x256, -1, -1, G320x400x256, -1, -1 },
  178.    { -1, -1, -1, -1, G640x350x16, -1 },
  179.    { G640x480x256, G640x480x32K, G640x480x64K, G640x480x256, G640x480x16, G640x480x16M32 },
  180.    { G800x600x256, G800x600x32K, G800x600x64K, G800x600x256, G800x600x16, G800x600x16M32 },
  181.    { G1024x768x256, G1024x768x32K, G1024x768x64K, G1024x768x256, G1024x768x16, G1024x768x16M32 },
  182.    { G1152x864x256, G1152x864x32K, G1152x864x64K, G1152x864x256, G1152x864x16, G1152x864x16M32 },
  183.    { G1280x1024x256, G1280x1024x32K, G1280x1024x64K, G1280x1024x256, G1280x1024x16, G1280x1024x16M32 }
  184.  };
  185.  
  186. static int mode_bitdepth[MAX_COLOR_MODES+1][3] =
  187.   { { 8, 8, 0 }, { 15, 16, 0 }, { 16, 16, 0 }, { 8, 8, 1 }, { 4, 8, 1 }, { 24, 32, 0 } };
  188.  
  189. struct bstring *video_mode_menu = NULL;
  190.  
  191. void flush_line(int y)
  192. {
  193.     int target_y = y;
  194.     char *addr;
  195.  
  196.     if (linear_mem != NULL && !need_dither)
  197.     return;
  198.  
  199.     addr = gfxvidinfo.linemem;
  200.     if (addr == NULL)
  201.     addr = gfxvidinfo.bufmem + y*gfxvidinfo.rowbytes;
  202.  
  203.     if (linear_mem == NULL) {
  204.     if (target_y < modeinfo.height && target_y >= 0) {
  205.         if (need_dither) {
  206.         DitherLine(dither_buf, (uae_u16 *)addr, 0, y, gfxvidinfo.width, bit_unit);
  207.         addr = dither_buf;
  208.         }
  209.         vga_drawscanline(target_y, addr);
  210.     }
  211.     } else {
  212.     if (need_dither && target_y >= 0) {
  213.         DitherLine(linear_mem + modeinfo.linewidth * target_y, (uae_u16 *)addr, 0, y,
  214.                gfxvidinfo.width, bit_unit);
  215.     }
  216.     }
  217. }
  218.  
  219. void flush_block(int a, int b)
  220. {
  221.     abort();
  222. }
  223.  
  224. void flush_screen(int a, int b)
  225. {
  226. }
  227.  
  228. static int colors_allocated;
  229. static long palette_entries[256][3];
  230.  
  231. static void restore_vga_colors (void)
  232. {
  233.     int i;
  234.     if (gfxvidinfo.pixbytes != 1)
  235.     return;
  236.     for (i = 0; i < 256; i++)
  237.     vga_setpalette (i, palette_entries[i][0], palette_entries[i][1], palette_entries[i][2]);
  238. }
  239.  
  240. static int get_color(int r, int g, int b, xcolnr *cnp)
  241. {
  242.     if (colors_allocated == 256)
  243.     return -1;
  244.     *cnp = colors_allocated;
  245.     palette_entries[colors_allocated][0] = doMask(r, 6, 0);
  246.     palette_entries[colors_allocated][1] = doMask(g, 6, 0);
  247.     palette_entries[colors_allocated][2] = doMask(b, 6, 0);
  248.     vga_setpalette(colors_allocated, doMask(r, 6, 0), doMask(g, 6, 0), doMask(b, 6, 0));
  249.     colors_allocated++;
  250.     return 1;
  251. }
  252.  
  253. static void init_colors(void)
  254. {
  255.     int i;
  256.     if (need_dither) {
  257.     setup_dither(bitdepth, get_color);
  258.     } else {
  259.     int rw = 5, gw = 5, bw = 5;
  260.     colors_allocated = 0;
  261.     if (currprefs.color_mode == 2) gw = 6;
  262.  
  263.     switch (gfxvidinfo.pixbytes) {
  264.      case 4:
  265.         alloc_colors64k(8, 8, 8, 16, 8, 0);
  266.         break;
  267.      case 2:
  268.         alloc_colors64k(rw, gw, bw, gw+bw, bw, 0);
  269.         break;
  270.      case 1:
  271.         alloc_colors256(get_color);
  272.         break;
  273.      default:
  274.         abort();
  275.     }
  276.     }
  277.     switch (gfxvidinfo.pixbytes) {
  278.      case 2:
  279.     for (i = 0; i < 4096; i++)
  280.         xcolors[i] = xcolors[i] * 0x00010001;
  281.     gfxvidinfo.can_double = 1;
  282.     break;
  283.      case 1:
  284.     for (i = 0; i < 4096; i++)
  285.         xcolors[i] = xcolors[i] * 0x01010101;
  286.     gfxvidinfo.can_double = 1;
  287.     break;
  288.      default:
  289.     gfxvidinfo.can_double = 0;
  290.     break;
  291.     }
  292. }
  293.  
  294. static int keystate[256];
  295.  
  296. static int scancode2amiga(int scancode)
  297. {
  298.     switch(scancode) {
  299.      case SCODE_A: return AK_A;
  300.      case SCODE_B: return AK_B;
  301.      case SCODE_C: return AK_C;
  302.      case SCODE_D: return AK_D;
  303.      case SCODE_E: return AK_E;
  304.      case SCODE_F: return AK_F;
  305.      case SCODE_G: return AK_G;
  306.      case SCODE_H: return AK_H;
  307.      case SCODE_I: return AK_I;
  308.      case SCODE_J: return AK_J;
  309.      case SCODE_K: return AK_K;
  310.      case SCODE_L: return AK_L;
  311.      case SCODE_M: return AK_M;
  312.      case SCODE_N: return AK_N;
  313.      case SCODE_O: return AK_O;
  314.      case SCODE_P: return AK_P;
  315.      case SCODE_Q: return AK_Q;
  316.      case SCODE_R: return AK_R;
  317.      case SCODE_S: return AK_S;
  318.      case SCODE_T: return AK_T;
  319.      case SCODE_U: return AK_U;
  320.      case SCODE_V: return AK_V;
  321.      case SCODE_W: return AK_W;
  322.      case SCODE_X: return AK_X;
  323.      case SCODE_Y: return AK_Y;
  324.      case SCODE_Z: return AK_Z;
  325.  
  326.      case SCODE_0: return AK_0;
  327.      case SCODE_1: return AK_1;
  328.      case SCODE_2: return AK_2;
  329.      case SCODE_3: return AK_3;
  330.      case SCODE_4: return AK_4;
  331.      case SCODE_5: return AK_5;
  332.      case SCODE_6: return AK_6;
  333.      case SCODE_7: return AK_7;
  334.      case SCODE_8: return AK_8;
  335.      case SCODE_9: return AK_9;
  336.  
  337.      case SCODE_KEYPAD0: return AK_NP0;
  338.      case SCODE_KEYPAD1: return AK_NP1;
  339.      case SCODE_KEYPAD2: return AK_NP2;
  340.      case SCODE_KEYPAD3: return AK_NP3;
  341.      case SCODE_KEYPAD4: return AK_NP4;
  342.      case SCODE_KEYPAD5: return AK_NP5;
  343.      case SCODE_KEYPAD6: return AK_NP6;
  344.      case SCODE_KEYPAD7: return AK_NP7;
  345.      case SCODE_KEYPAD8: return AK_NP8;
  346.      case SCODE_KEYPAD9: return AK_NP9;
  347.  
  348.      case SCODE_KEYPADADD: return AK_NPADD;
  349.      case SCODE_KEYPADSUB: return AK_NPSUB;
  350.      case SCODE_KEYPADMUL: return AK_NPMUL;
  351.      case SCODE_KEYPADDIV: return AK_NPDIV;
  352.      case SCODE_KEYPADRET: return AK_ENT;
  353.      case SCODE_KEYPADDOT: return AK_NPDEL;
  354.  
  355.      case SCODE_F1: return AK_F1;
  356.      case SCODE_F2: return AK_F2;
  357.      case SCODE_F3: return AK_F3;
  358.      case SCODE_F4: return AK_F4;
  359.      case SCODE_F5: return AK_F5;
  360.      case SCODE_F6: return AK_F6;
  361.      case SCODE_F7: return AK_F7;
  362.      case SCODE_F8: return AK_F8;
  363.      case SCODE_F9: return AK_F9;
  364.      case SCODE_F10: return AK_F10;
  365.  
  366.      case SCODE_BS: return AK_BS;
  367.      case SCODE_LCONTROL: return AK_CTRL;
  368.      case SCODE_RCONTROL: return AK_RCTRL;
  369.      case SCODE_TAB: return AK_TAB;
  370.      case SCODE_LALT: return AK_LALT;
  371.      case SCODE_RALT: return AK_RALT;
  372.      case SCODE_ENTER: return AK_RET;
  373.      case SCODE_SPACE: return AK_SPC;
  374.      case SCODE_LSHIFT: return AK_LSH;
  375.      case SCODE_RSHIFT: return AK_RSH;
  376.      case SCODE_ESCAPE: return AK_ESC;
  377.  
  378.      case SCODE_INSERT: return AK_HELP;
  379.      case SCODE_END: return AK_NPRPAREN;
  380.      case SCODE_HOME: return AK_NPLPAREN;
  381.  
  382.      case SCODE_DELETE: return AK_DEL;
  383.      case SCODE_CB_UP: return AK_UP;
  384.      case SCODE_CB_DOWN: return AK_DN;
  385.      case SCODE_CB_LEFT: return AK_LF;
  386.      case SCODE_CB_RIGHT: return AK_RT;
  387.  
  388.      case SCODE_PRTSCR: return AK_BACKSLASH;
  389.      case SCODE_asciicircum: return AK_BACKQUOTE;
  390.      case SCODE_bracketleft: return AK_LBRACKET;
  391.      case SCODE_bracketright: return AK_RBRACKET;
  392.      case SCODE_comma: return AK_COMMA;
  393.      case SCODE_period: return AK_PERIOD;
  394.      case SCODE_slash: return AK_SLASH;
  395.      case SCODE_semicolon: return AK_SEMICOLON;
  396.      case SCODE_grave: return AK_QUOTE;
  397.      case SCODE_minus: return AK_MINUS;
  398.      case SCODE_equal: return AK_EQUAL;
  399.  
  400.     /* This one turns off screen updates. */
  401.      case SCODE_SLOCK: return AK_inhibit;
  402.  
  403.      case SCODE_PGUP: case SCODE_RWIN95: return AK_RAMI;
  404.      case SCODE_PGDN: case SCODE_LWIN95: return AK_LAMI;
  405.  
  406. /*#ifdef KBD_LANG_DE*/
  407.      case SCODE_numbersign: return AK_NUMBERSIGN;
  408.      case SCODE_ltgt: return AK_LTGT;
  409. /*#endif*/
  410.     }
  411.     return -1;
  412. }
  413.  
  414. static void my_kbd_handler(int scancode, int newstate)
  415. {
  416.     int akey = scancode2amiga(scancode);
  417.  
  418.     assert(scancode >= 0 && scancode < 0x100);
  419.     if (scancode == SCODE_F12) {
  420.     uae_quit ();
  421.     } else if (scancode == SCODE_F11) {
  422.     gui_requested = 1;
  423.     }
  424.     if (keystate[scancode] == newstate)
  425.     return;
  426.     keystate[scancode] = newstate;
  427.  
  428.     if (akey == -1) {
  429.     return;
  430.     }
  431.  
  432.     if (newstate == KEY_EVENTPRESS) {
  433.     if (akey == AK_inhibit)
  434.         toggle_inhibit_frame (0);
  435.     else
  436.         record_key (akey << 1);
  437.     } else
  438.     record_key ((akey << 1) | 1);
  439.  
  440.     /* "Affengriff" */
  441.     if(keystate[AK_CTRL] && keystate[AK_LAMI] && keystate[AK_RAMI])
  442.     uae_reset();
  443. }
  444.  
  445. static void leave_graphics_mode (void)
  446. {
  447.     keyboard_close ();
  448.     mouse_close ();
  449.     sleep(1); /* Maybe this will fix the "screen full of garbage" problem */
  450.     current_vgamode = TEXT;
  451.     vga_setmode(TEXT);
  452. }
  453.  
  454. static int post_enter_graphics (void)
  455. {
  456.     vga_setmousesupport(1);
  457.     mouse_init("/dev/mouse", vga_getmousetype(), 10);
  458.     if (keyboard_init() != 0) {
  459.     leave_graphics_mode ();
  460.     fprintf (stderr, "Are you sure you have a keyboard??\n");
  461.     return 0;
  462.     }
  463.     keyboard_seteventhandler (my_kbd_handler);
  464.     keyboard_translatekeys (DONT_CATCH_CTRLC);
  465.  
  466.     mouse_setxrange(-1000,1000);
  467.     mouse_setyrange(-1000,1000);
  468.     mouse_setposition(0,0);
  469.  
  470.     return 1;
  471. }
  472.  
  473. static int enter_graphics_mode (int which)
  474. {
  475.     int oldmode = current_vgamode;
  476.     if (vga_setmode(which) < 0) {
  477.     sleep(1);
  478.     vga_setmode(TEXT);
  479.     fprintf(stderr, "SVGAlib doesn't like my video mode. Giving up.\n");
  480.     return 0;
  481.     }
  482.     current_vgamode = which;
  483.  
  484.     linear_mem = 0;
  485.     if ((modeinfo.flags & CAPABLE_LINEAR) && !currprefs.no_xhair) {
  486.     int val = vga_setlinearaddressing();
  487.     int new_ul = val != -1 ? !need_dither : 0;
  488.     if (using_linear == -1)
  489.         using_linear = new_ul;
  490.     else
  491.         if (using_linear != new_ul) {
  492.         leave_graphics_mode ();
  493.         fprintf (stderr, "SVGAlib feeling not sure about linear modes???\n");
  494.         abort ();
  495.         }
  496.     if (val != -1) {
  497.         linear_mem = (char *)vga_getgraphmem();
  498.         fprintf(stderr, "Using linear addressing: %p.\n", linear_mem);
  499.     }
  500.     }
  501.  
  502.     return post_enter_graphics ();
  503. }
  504.  
  505. static int enter_graphics_mode_picasso (int which)
  506. {
  507.     int oldmode = current_vgamode;
  508.     if (which == oldmode)
  509.     return 1;
  510.  
  511.     if (vga_setmode(which) < 0) {
  512.     sleep(1);
  513.     vga_setmode(TEXT);
  514.     fprintf(stderr, "SVGAlib doesn't like my video mode. Giving up.\n");
  515.     exit (1);
  516.     }
  517.     current_vgamode = which;
  518.  
  519.     linear_mem = 0;
  520.     if ((modeinfo.flags & CAPABLE_LINEAR) && !currprefs.no_xhair) {
  521.     int val = vga_setlinearaddressing();
  522.     if (val != -1) {
  523.         linear_mem = (char *)vga_getgraphmem();
  524.         fprintf(stderr, "Using linear addressing: %p.\n", linear_mem);
  525.     }
  526.     }
  527.  
  528.     keyboard_close ();
  529.     mouse_close ();
  530.     return post_enter_graphics ();
  531. }
  532.  
  533. int graphics_setup(void)
  534. {
  535.     int i,j, count = 1;
  536.  
  537.     vga_init();
  538.  
  539.     current_vgamode = TEXT;
  540.  
  541.     for (i = 0; i < MAX_SCREEN_MODES; i++) {
  542.     /* Ignore the larger modes which only make sense for Picasso screens.  */
  543.     if (x_size_table[i] > 800 || y_size_table[i] > 600)
  544.         continue;
  545.  
  546.     for (j = 0; j < MAX_COLOR_MODES+1; j++) {
  547.         /* Delete modes which are not available on this card.  */
  548.         if (!vga_hasmode (vga_mode_table[i][j])) {
  549.         vga_mode_table[i][j] = -1;
  550.         }
  551.  
  552.         if (vga_mode_table[i][j] != -1)
  553.         count++;
  554.     }
  555.     }
  556.  
  557.     video_mode_menu = (struct bstring *)malloc(sizeof (struct bstring)*count);
  558.     memset(video_mode_menu, 0, sizeof (struct bstring)*count);
  559.     count=0;
  560.  
  561.     for (i = 0; i < MAX_SCREEN_MODES; i++) {
  562.     /* Ignore the larger modes which only make sense for Picasso screens.  */
  563.     if (x_size_table[i] > 800 || y_size_table[i] > 600)
  564.         continue;
  565.  
  566.     for (j = 0; j < MAX_COLOR_MODES+1; j++) {
  567.         char buf[80];
  568.         if (vga_mode_table[i][j] == -1)
  569.         continue;
  570.  
  571.         sprintf(buf, "%3dx%d, %s", x_size_table[i], y_size_table[i],
  572.             colormodes[j]);
  573.         video_mode_menu[count].val = -1;
  574.         video_mode_menu[count++].data = strdup(buf);
  575.     }
  576.     }
  577.     video_mode_menu[count].val = -3;
  578.     video_mode_menu[count++].data = NULL;
  579.     return 1;
  580. }
  581.  
  582. void vidmode_menu_selected(int m)
  583. {
  584.     int i, j;
  585.     for (i = 0; i < MAX_SCREEN_MODES; i++) {
  586.     /* Ignore the larger modes which only make sense for Picasso screens.  */
  587.     if (x_size_table[i] > 800 || y_size_table[i] > 600)
  588.         continue;
  589.     for (j = 0; j < MAX_COLOR_MODES+1; j++) {
  590.         if (vga_mode_table[i][j] != -1)
  591.         if (!m--)
  592.             goto found;
  593.  
  594.     }
  595.     }
  596.     abort();
  597.  
  598.     found:
  599.     currprefs.gfx_width = x_size_table[i];
  600.     currprefs.gfx_height = y_size_table[i];
  601.     currprefs.color_mode = j;
  602. }
  603.  
  604. static int select_mode_from_prefs (void)
  605. {
  606.     int mode_nr0, mode_nr;
  607.     int i;
  608.  
  609.     if (currprefs.color_mode > 5)
  610.     fprintf(stderr, "Bad color mode selected. Using default.\n"), currprefs.color_mode = 0;
  611.  
  612.     mode_nr0 = 0;
  613.     for (i = 1; i < MAX_SCREEN_MODES; i++) {
  614.     if (x_size_table[mode_nr0] >= currprefs.gfx_width)
  615.         break;
  616.     if (x_size_table[i-1] != x_size_table[i])
  617.         mode_nr0 = i;
  618.     }
  619.     mode_nr = -1;
  620.     for (i = mode_nr0; i < MAX_SCREEN_MODES && x_size_table[i] == x_size_table[mode_nr0]; i++) {
  621.     if ((y_size_table[i] >= currprefs.gfx_height
  622.          || i + 1 == MAX_SCREEN_MODES
  623.          || x_size_table[i+1] != x_size_table[mode_nr0])
  624.         && vga_mode_table[i][currprefs.color_mode] != -1)
  625.     {
  626.         mode_nr = i;
  627.         break;
  628.     }
  629.     }
  630.     if (mode_nr == -1) {
  631.     fprintf(stderr, "Sorry, this combination of color and video mode is not supported.\n");
  632.     return 0;
  633.     }
  634.     vgamode = vga_mode_table[mode_nr][currprefs.color_mode];
  635.     if (vgamode == -1) {
  636.     fprintf(stderr, "Bug!\n");
  637.     abort();
  638.     }
  639.     fprintf(stderr, "Desired resolution: %dx%d, using: %dx%d\n",
  640.         currprefs.gfx_width, currprefs.gfx_height,
  641.         x_size_table[mode_nr], y_size_table[mode_nr]);
  642.  
  643.     currprefs.gfx_width = x_size_table[mode_nr];
  644.     currprefs.gfx_height = y_size_table[mode_nr];
  645.  
  646.     return 1;
  647. }
  648.  
  649. int graphics_init(void)
  650. {
  651.     int i;
  652.     need_dither = 0;
  653.     screen_is_picasso = 0;
  654.  
  655.     if (!select_mode_from_prefs ())
  656.     return 0;
  657.  
  658.     bitdepth = mode_bitdepth[currprefs.color_mode][0];
  659.     bit_unit = mode_bitdepth[currprefs.color_mode][1];
  660.     need_dither = mode_bitdepth[currprefs.color_mode][2];
  661.  
  662.     modeinfo = *vga_getmodeinfo (vgamode);
  663.  
  664.     gfxvidinfo.pixbytes = modeinfo.bytesperpixel;
  665.     if (!need_dither) {
  666.     if (modeinfo.bytesperpixel == 0) {
  667.         printf("Got a bogus value from SVGAlib...\n");
  668.         gfxvidinfo.pixbytes = 1;
  669.     }
  670.     } else {
  671.     gfxvidinfo.pixbytes = 2;
  672.     }
  673.  
  674.     using_linear = -1;
  675.  
  676.     if (!enter_graphics_mode (vgamode))
  677.     return 0;
  678.  
  679.     sleep(2);
  680.     gfxvidinfo.maxblocklines = 0;
  681.  
  682.     gfxvidinfo.width = modeinfo.width;
  683.     gfxvidinfo.height = modeinfo.height;
  684.  
  685.     if (linear_mem != NULL && !need_dither) {
  686.     gfxvidinfo.bufmem = linear_mem;
  687.     gfxvidinfo.rowbytes = modeinfo.linewidth;
  688.     } else {
  689.     gfxvidinfo.rowbytes = (modeinfo.width * gfxvidinfo.pixbytes + 3) & ~3;
  690. #if 1
  691.     gfxvidinfo.bufmem = malloc(gfxvidinfo.rowbytes);
  692.     gfxvidinfo.linemem = gfxvidinfo.bufmem;
  693.     memset(gfxvidinfo.bufmem, 0, gfxvidinfo.rowbytes);
  694. #else
  695.     gfxvidinfo.bufmem = malloc(gfxvidinfo.rowbytes * modeinfo.height);
  696.     memset(gfxvidinfo.bufmem, 0, gfxvidinfo.rowbytes * modeinfo.height);
  697. #endif
  698.     }
  699.  
  700.     init_colors();
  701.     buttonstate[0] = buttonstate[1] = buttonstate[2] = 0;
  702.     for(i = 0; i < 256; i++)
  703.     keystate[i] = 0;
  704.  
  705.     lastmx = lastmy = 0;
  706.     newmousecounters = 0;
  707.  
  708.     return 1;
  709. }
  710.  
  711. void graphics_leave(void)
  712. {
  713.     leave_graphics_mode ();
  714.     dumpcustom();
  715. }
  716.  
  717. void handle_events(void)
  718. {
  719.     int button = mouse_getbutton();
  720.  
  721.     gui_requested = 0;
  722.     keyboard_update();
  723.     mouse_update();
  724.     lastmx += mouse_getx();
  725.     lastmy += mouse_gety();
  726.     mouse_setposition(0,0);
  727.  
  728.     buttonstate[0] = button & 4;
  729.     buttonstate[1] = button & 2;
  730.     buttonstate[2] = button & 1;
  731.  
  732. #ifdef PICASSO96
  733.     if (screen_is_picasso && !picasso_vidinfo.extra_mem) {
  734.     int i;
  735.     char *addr = gfxmemory + (picasso96_state.Address - gfxmem_start);
  736.     for (i = 0; i < picasso_vidinfo.height; i++, addr += picasso96_state.BytesPerRow) {
  737.         if (!picasso_invalid_lines[i])
  738.         continue;
  739.         picasso_invalid_lines[i] = 0;
  740.         vga_drawscanline(i, addr);
  741.     }
  742.     }
  743. #endif
  744.  
  745.     if (!screen_is_picasso && gui_requested) {
  746.     leave_graphics_mode ();
  747.     gui_changesettings ();
  748.     enter_graphics_mode (vgamode);
  749.     if (linear_mem != NULL && !need_dither)
  750.         gfxvidinfo.bufmem = linear_mem;
  751.     restore_vga_colors ();
  752.     notice_screen_contents_lost ();
  753.     }
  754. }
  755.  
  756. int debuggable(void)
  757. {
  758.     return 0;
  759. }
  760.  
  761. int needmousehack(void)
  762. {
  763.     return 0;
  764. }
  765.  
  766. void LED(int on)
  767. {
  768. }
  769.  
  770. void write_log (const char *buf)
  771. {
  772.     fprintf (stderr, buf);
  773. }
  774.  
  775. #ifdef PICASSO96
  776.  
  777. void DX_Invalidate (int first, int last)
  778. {
  779.     do {
  780.     picasso_invalid_lines[first] = 1;
  781.     first++;
  782.     } while (first <= last);
  783. }
  784.  
  785. int DX_BitsPerCannon (void)
  786. {
  787.     return 8;
  788. }
  789.  
  790. void DX_SetPalette(int start, int count)
  791. {
  792.     if (!screen_is_picasso || picasso_vidinfo.pixbytes != 1)
  793.     return;
  794.  
  795.     while (count-- > 0) {
  796.     vga_setpalette(start, picasso96_state.CLUT[start].Red * 63 / 255,
  797.                picasso96_state.CLUT[start].Green * 63 / 255,
  798.                picasso96_state.CLUT[start].Blue * 63 / 255);
  799.     start++;
  800.     }
  801. }
  802.  
  803. int DX_FillResolutions (uae_u16 *ppixel_format)
  804. {
  805.     int i, count = 0;
  806.     uae_u16 format = 0;
  807.  
  808.     for (i = 0; i < MAX_SCREEN_MODES; i++) {
  809.     int mode = vga_mode_table[i][0];
  810.     if (mode != -1) {
  811.         DisplayModes[count].res.width = x_size_table[i];
  812.         DisplayModes[count].res.height = y_size_table[i];
  813.         DisplayModes[count].depth = 1;
  814.         DisplayModes[count].refresh = 75;
  815.         count++;
  816.         format |= RGBFF_CHUNKY;
  817.     }
  818.     mode = vga_mode_table[i][2];
  819.     if (mode != -1) {
  820.         DisplayModes[count].res.width = x_size_table[i];
  821.         DisplayModes[count].res.height = y_size_table[i];
  822.         DisplayModes[count].depth = 2;
  823.         DisplayModes[count].refresh = 75;
  824.         count++;
  825.         format |= RGBFF_R5G6B5PC;
  826.     }
  827.     mode = vga_mode_table[i][5];
  828.     if (mode != -1) {
  829.         DisplayModes[count].res.width = x_size_table[i];
  830.         DisplayModes[count].res.height = y_size_table[i];
  831.         DisplayModes[count].depth = 4;
  832.         DisplayModes[count].refresh = 75;
  833.         count++;
  834.         format |= RGBFF_B8G8R8A8;
  835.     }
  836.     }
  837.  
  838.     *ppixel_format = format;
  839.     return count;
  840. }
  841.  
  842. static void set_window_for_picasso (void)
  843. {
  844.     enter_graphics_mode_picasso (picasso_vgamode);
  845.     if (linear_mem != NULL)
  846.     picasso_vidinfo.extra_mem = 1;
  847.     else
  848.     picasso_vidinfo.extra_mem = 0;
  849.     printf ("em: %d\n", picasso_vidinfo.extra_mem);
  850.     DX_SetPalette (0, 256);
  851. }
  852.  
  853. static void set_window_for_amiga (void)
  854. {
  855.     leave_graphics_mode ();
  856.     enter_graphics_mode (vgamode);
  857.     if (linear_mem != NULL && !need_dither)
  858.     gfxvidinfo.bufmem = linear_mem;
  859.  
  860.     restore_vga_colors ();
  861. }
  862.  
  863. void gfx_set_picasso_modeinfo (int w, int h, int depth)
  864. {
  865.     vga_modeinfo *info;
  866.     int i, mode;
  867.  
  868.     for (i = 0; i < MAX_SCREEN_MODES; i++)
  869.     if (x_size_table[i] == w && y_size_table[i] == h)
  870.         break;
  871.     printf ("::: %d %d %d, %d\n", w, h, depth, i);
  872.     if (i == MAX_SCREEN_MODES)
  873.     abort ();
  874.     mode = (depth == 8 ? vga_mode_table[i][0]
  875.         : depth == 16 ? vga_mode_table[i][2]
  876.         : depth == 32 ? vga_mode_table[i][5]
  877.         : -1);
  878.     printf ("::: %d\n", mode);
  879.     if (mode == -1)
  880.     abort ();
  881.  
  882.     info = vga_getmodeinfo (mode);
  883.     printf ("::: %d\n", info->linewidth);
  884.     picasso_vgamode = mode;
  885.     picasso_vidinfo.width = w;
  886.     picasso_vidinfo.height = h;
  887.     picasso_vidinfo.depth = depth;
  888.     picasso_vidinfo.pixbytes = depth>>3;
  889.     picasso_vidinfo.rowbytes = info->linewidth;
  890.     if (screen_is_picasso)
  891.     set_window_for_picasso ();
  892. }
  893.  
  894. void gfx_set_picasso_baseaddr (uaecptr a)
  895. {
  896. }
  897.  
  898. void gfx_set_picasso_state (int on)
  899. {
  900.     if (on == screen_is_picasso)
  901.     return;
  902.     screen_is_picasso = on;
  903.     if (on)
  904.     set_window_for_picasso ();
  905.     else
  906.     set_window_for_amiga ();
  907. }
  908.  
  909. void begindrawing (void)
  910. {
  911. }
  912.  
  913. void enddrawing (void)
  914. {
  915. }
  916.  
  917. uae_u8 *lockscr (void)
  918. {
  919.     return linear_mem;
  920. }
  921. void unlockscr (void)
  922. {
  923. }
  924. #endif
  925.